package _REPLACE_THIS_STRING_WITH_TARGET_PACKAGE_;

import java.util.List;

import org.junit.Assert;
import org.springframework.beans.factory.annotation.Autowired;

import cucumber.api.java.en.And;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;

public class <entity>Steps {
	
	@Autowired
	private <entity>DataOnDemand dod;
	
	private long count;
	
	private <entity> dod<entity>;
	private <entity> persistent<entity>;
	private <entity> merged<entity>;
	private <entity> transient<entity>;

	private boolean modified;

	private Integer currentVersion;
	
	@Given("^I have <entity> data on demand.$")
	public void I_have_<entity>_data_on_demand() throws Throwable {
		dod<entity> = dod.getRandom<entity>();
        Assert.assertNotNull("Data on demand for '<entity>' failed to initialize correctly", dod<entity>);
        Long id = dod<entity>.getId();
        Assert.assertNotNull("Data on demand for '<entity>' failed to provide an identifier", id);
	}

	@When("^I count <entities>$")
	public void I_count_<entities>() throws Throwable {
		count = <entity>.count<entities>();
	}

	@Then("^I should have at least one <entity>.$")
	public void I_should_have_at_least_one_<entity>() throws Throwable {
		Assert.assertTrue("Counter for '<entity>' incorrectly reported there were no entries", count > 0);
	}

	@When("^I find a random <entity>.$")
	public void I_find_a_random_<entity>() throws Throwable {
		persistent<entity> = <entity>.find<entity>(dod<entity>.getId());
		Assert.assertNotNull("Find method for '<entity>' illegally returned null for id '" + dod<entity>.getId(), persistent<entity>);
	}

	@Then("^the <entity> id's should match.$")
	public void the_<entity>_id_s_should_match() throws Throwable {
		Assert.assertEquals("Find method for '<entity>' returned the incorrect identifier", dod<entity>.getId(), persistent<entity>.getId());
	}

	@Given("^there are not too many <entities>.$")
	public void there_are_not_too_many_<entities>() throws Throwable {
		Assert.assertTrue("Too expensive to perform a find all test for '<entity>', as there are " + count + " entries.", count < 100);
	}

	@Then("^I should have more than one <entity>.$")
	public void I_should_have_more_than_one_<entity>() throws Throwable {
		List<<entity>> result = <entity>.findAll<entities>();
        Assert.assertNotNull("Find all method for '<entity>' illegally returned null", result);
        Assert.assertTrue("Find all method for '<entity>' failed to return any data", result.size() > 0);
	}

	@Given("^I count at most (\\d+) <entities>.$")
	public void I_find_at_most_<entity>_s(int max) throws Throwable {
		I_count_<entities>();
		if (count > max) count = max;
	}

	@Then("^I should find the same amount of <entities>.$")
	public void I_should_find_same_amount_of_<entities>() throws Throwable {
		int firstResult = 0;
        int maxResults = (int) count;
        List<<entity>> result = <entity>.find<entity>Entries(firstResult, maxResults);
        Assert.assertNotNull("Find entries method for '<entity>' illegally returned null", result);
        Assert.assertEquals("Find entries method for '<entity>' returned an incorrect number of entries", count, result.size());
	}

	@When("^I flush that <entity>.$")
	public void I_flush_that_<entity>() throws Throwable {
		I_find_a_random_<entity>();
		modified =  dod.modify<entity>(persistent<entity>);
        currentVersion = persistent<entity>.getVersion();
        persistent<entity>.flush();
	}

	@Then("^the <entity> version should increment.$")
	public void the_<entity>_version_should_increment() throws Throwable {
		Assert.assertTrue("Version for '<entity>' failed to increment on flush directive", (currentVersion != null && dod<entity>.getVersion() > currentVersion) || !modified);
	}

	@When("^I modify a <entity>.$")
	public void I_modify_a_<entity>() throws Throwable {
		modified =  dod.modify<entity>(dod<entity>);
	    I_find_a_random_<entity>();
		currentVersion = persistent<entity>.getVersion();
	    merged<entity> = persistent<entity>.merge();
	    persistent<entity>.flush();
	}

	@Then("^the <entity> should be merged.$")
	public void the_<entity>_should_be_merged() throws Throwable {
		Assert.assertEquals("Identifier of merged object not the same as identifier of original object", merged<entity>.getId(), dod<entity>.getId());
	    Assert.assertTrue("Version for '<entity>' failed to increment on merge and flush directive", (currentVersion != null && persistent<entity>.getVersion() > currentVersion) || !modified);
	}
	
	@And("^I have a transient <entity>.$")
	public void I_have_a_transient_<entity>() throws Throwable {
		transient<entity> = dod.getNewTransient<entity>(Integer.MAX_VALUE);
        Assert.assertNotNull("Data on demand for '<entity>' failed to provide a new transient entity", transient<entity>);
        Assert.assertNull("Expected '<entity>' identifier to be null", transient<entity>.getId());        
	}

	@When("^I persist a <entity>.$")
	public void I_persist_a_<entity>() throws Throwable {
		transient<entity>.persist();
		transient<entity>.flush();
	}

	@Then("^the <entity> should be persisted.$")
	public void the_<entity>_should_be_persisted() throws Throwable {
		Assert.assertNotNull("Expected '<entity>' identifier to no longer be null", dod<entity>.getId());
	}

	@When("^I remove a <entity>.$")
	public void I_remove_a_<entity>() throws Throwable {
		I_find_a_random_<entity>();
		persistent<entity>.remove();
		persistent<entity>.flush();
	}

	@Then("^the <entity> should be removed.$")
	public void the_<entity>_should_be_removed() throws Throwable {
		Assert.assertNull("Failed to remove '<entity>' with identifier '" + persistent<entity>.getId() + "'", <entity>.find<entity>(persistent<entity>.getId()));
	}

}
